<?php
namespace app\task\controller;
use app\BaseController;
use app\common\model\mysql\YwProjectSubmitRecord;
use think\facade\Log;

class Task extends BaseController
{

    public function initialize()
    {
    }

    public function checkProject(){
        $lists = YwProjectSubmitRecord::WHERE(['is_check'=>0])->select();
        $fileClient = new \FileClient();
        if(!empty($lists)){
            foreach ($lists as $item){
                //这里先解压，解压前先判断有没有解压的文件，有就删除
                $fileClient->deleteModule(env('api_url').'/uploads/project/api');
                $fileClient->unzip($item['zip_str']);
                //读取指定文件内容
                //这里是判断路由的核心代码以及计算代码的行数
                $line_count_all = 0;
                //路由释义
                $route_str = '';
                //驼峰命名释义
                $hump_str = '';
                //方法注释
                $func_str = '';
                //引入释义
                $lead_into_str = '';
                //admin模块的检查
                //先把路由文件解析出来
                $routeArr = $fileClient->readRouteFile($_SERVER["DOCUMENT_ROOT"].\FileClient::$admin_path.'/route/app.php');
                $routeList = $fileClient->handleRouteList($routeArr);
                //这里检测路由定义的规范性，强制要求每个路由上面必须写注释
                $route_notr_norm_str = '';
                if(!$fileClient->checkRouteNoteIsNorm($_SERVER["DOCUMENT_ROOT"].\FileClient::$admin_path.'/route/app.php')){
                    $route_notr_norm_str .= 'admin模块下的路由定义文件未符合既规范<br>';
                }
                //获取admin模块下controller
                $admin_controller_arr = $fileClient->selectOnlyModule($_SERVER["DOCUMENT_ROOT"].\FileClient::$admin_path.'/controller');
                foreach ($admin_controller_arr as $file_name){
                    if($file_name != 'Error.php'){
                        $file_name_arr = explode('.',$file_name);
                        if(isset($routeList[$file_name_arr[0]])){
                            $ownRouteList = $routeList[$file_name_arr[0]];
                        }else{
                            $ownRouteList = [];
                        }
                        $content = $fileClient->readFile($_SERVER["DOCUMENT_ROOT"].\FileClient::$admin_path.'/controller/'.$file_name);
                        $line_count_all += substr_count($content,"<br>");
                        $functionListAll = $fileClient->checkContentFunction($content);
                        $functionStrList = $functionListAll[0];
                        //检查方法上是否有注释
                        $funcIsValid = $fileClient->checkFunctionStr($functionStrList,explode('<br>',$content));
                        if(!$funcIsValid){
                            $func_str .= 'admin下controller类【'.$file_name.'】的方法没有注释<br>';
                        }
                        //检查引入是否有固定的注释
                        $leadIntoIsValid = $fileClient->checkLeadInto(explode('<br>',$content));
                        if(!$leadIntoIsValid){
                            $lead_into_str .= 'admin下controller类【'.$file_name.'】引入规范有误<br>';
                        }
                        $functionList = $functionListAll[1];
                        //检查是否遵循驼峰命名
                        $isValid = $fileClient->checkFunctionNameIsValid($functionList);
                        if(!$isValid){
                            $hump_str .= 'admin下controller类【'.$file_name.'】的方法驼峰命名有误<br>';
                        }
                        if(!$fileClient->checkRouteAndFunction($ownRouteList,$functionList)){
                            $route_str .= 'admin下controller类【'.$file_name.'】的路由与方法不匹配<br>';
                        }
                    }
                }
                //api模块的检查
                $apiRouteArr = $fileClient->readRouteFile($_SERVER["DOCUMENT_ROOT"].\FileClient::$api_path.'/route/app.php');
                $apiRouteList = $fileClient->handleRouteList($apiRouteArr);
                if(!$fileClient->checkRouteNoteIsNorm($_SERVER["DOCUMENT_ROOT"].\FileClient::$api_path.'/route/app.php')){
                    $route_notr_norm_str .= 'api模块下的路由定义文件未符合既规范<br>';
                }
                //获取admin模块下controller
                $api_controller_arr = $fileClient->selectOnlyModule($_SERVER["DOCUMENT_ROOT"].\FileClient::$api_path.'/controller');
                //validate 验证模型
                $validate_require_alias_str = '';
                //service
                $service_require_alias_str = '';
                //方法返回注释
                $return_valid_str = '';
                //验证定义数据和获取数据
                $func_data_str = '';
                foreach ($api_controller_arr as $file_name){
                    if($file_name != 'Error.php'){
                        $file_name_arr = explode('.',$file_name);
                        if(isset($apiRouteList[$file_name_arr[0]])){
                            $ownRouteList = $apiRouteList[$file_name_arr[0]];
                        }else{
                            $ownRouteList = [];
                        }
                        $content = $fileClient->readFile($_SERVER["DOCUMENT_ROOT"].\FileClient::$api_path.'/controller/'.$file_name);
                        $line_count_all += substr_count($content,"<br>");
                        $functionListAll = $fileClient->checkContentFunction($content);
                        $functionStrList = $functionListAll[0];
                        //检查方法上是否有注释
                        $funcIsValid = $fileClient->checkFunctionStr($functionStrList,explode('<br>',$content));
                        if(!$funcIsValid){
                            $func_str .= 'api下controller类【'.$file_name.'】的方法没有注释<br>';
                        }
                        //检测方法里面的代码，第一行必须是接收参数定义，第二行为公共方法获取参数
                        $funcIsGetData = $fileClient->checkFunctiongetData($functionStrList,explode('<br>',$content));
                        if(!$funcIsGetData){
                            $func_data_str .= 'api下controller类【'.$file_name.'】的方法获取传参定义或获取数据有误<br>';
                        }
                        //方法的返回
                        //这里强制规定，方法的返回应写注释，【放发返回，然后下一行返回，直接校验函数即可】
                        if(!$fileClient->checkReturnIsValid(explode('<br>',$content))){
                            $return_valid_str .= 'api下controller类【'.$file_name.'】方法返回注释规范有误<br>';
                        }
                        //检查引入是否有固定的注释
                        $leadIntoIsValid = $fileClient->checkLeadInto(explode('<br>',$content));
                        if(!$leadIntoIsValid){
                            $lead_into_str .= 'api下controller类【'.$file_name.'】引入规范有误<br>';
                        }
                        $functionList = $functionListAll[1];
                        //检查是否遵循驼峰命名
                        $isValid = $fileClient->checkFunctionNameIsValid($functionList);
                        if(!$isValid){
                            $hump_str .= 'api下controller类【'.$file_name.'】的方法驼峰命名有误<br>';
                        }
                        if(!$fileClient->checkRouteAndFunction($ownRouteList,$functionList)){
                            $route_str .= 'api下controller类【'.$file_name.'】的路由与方法不匹配<br>';
                        }
                        //validate层引入强制规定必须设置别名as validateModel
                        if(!$fileClient->checkRequireAlias('as validateModel','use app\common\validate',explode('<br>',$content))){
                            $validate_require_alias_str .= 'api下controller类【'.$file_name.'】引入validate验证类别名有误<br>';
                        }
                        //service层引入强制规定必须设置别名as serviceModel
                        if(!$fileClient->checkRequireAlias('as serviceModel','use app\common\business\mysql',explode('<br>',$content))){
                            $service_require_alias_str .= 'api下controller类【'.$file_name.'】引入service类别名有误<br>';
                        }
                    }
                }
                //common模块
                //common模块主要是检查模型和service层与controller层是否对应
                //先检查模型层
                //获取common模块下model
                $common_model_arr = $fileClient->selectOnlyModule($_SERVER["DOCUMENT_ROOT"].\FileClient::$common_path.'/model/mysql');
                //然后再检查service层
                $common_service_arr = $fileClient->selectOnlyModule($_SERVER["DOCUMENT_ROOT"].\FileClient::$common_path.'/business/mysql');
                //这里强制要求validate验证层也必须和model层对应，不管是否有没有验证，没有可以建一个空类
                $common_validate_arr = $fileClient->selectOnlyModule($_SERVER["DOCUMENT_ROOT"].\FileClient::$common_path.'/validate');
                //业务模块
                //模型模块
                //验证模块
                //这里来校验common下的model，service，validate，以及admin模块下的controller
                //比较4个的结果
                $compare_str = '';
                if(count($common_model_arr) > 0){
                    foreach ($common_model_arr as $common_model){
                        if(!in_array($common_model,$admin_controller_arr)){
                            $compare_str .= 'admin模块控制器中未与模型【'.$common_model.'】对应<br>';
                        }
                        if(!in_array($common_model,$common_service_arr)){
                            $compare_str .= 'common模块service中未与模型【'.$common_model.'】对应<br>';
                        }
                        if(!in_array($common_model,$common_validate_arr)){
                            $compare_str .= 'common模块validate中未与模型【'.$common_model.'】对应<br>';
                        }
                    }
                }
                //模型是否有字段注释
                $common_model_schema_check_str = '';
                //针对每个字段注释检测
                $common_model_schema_remark_check_str = '';
                //这里校验model层的$schema
                if(count($common_model_arr) > 0){
                    foreach ($common_model_arr as $common_model_file_name){
                        $content = $fileClient->readFile($_SERVER["DOCUMENT_ROOT"].\FileClient::$common_path.'/model/mysql/'.$common_model_file_name);
                        //下检测有没有定义schema
                        if(strpos($content,'定义字段开始') === false || strpos($content,'定义字段结束') === false){
                            $common_model_schema_check_str .= '模型【'.$common_model_file_name.'】中未定义schema<br>';
                        }else{
                            $schmeaIsValid = $fileClient->checkCommonModelSchemaIsValid(explode('<br>',$content));
                            if(!$schmeaIsValid){
                                $common_model_schema_remark_check_str .= '模型【'.$common_model_file_name.'】中有字段注释不规范<br>';
                            }
                        }
                    }
                }
                //检查task目录
                //先把路由文件解析出来
                $taskRouteArr = $fileClient->readRouteFile($_SERVER["DOCUMENT_ROOT"].\FileClient::$task_path.'/route/app.php');
                $taskRouteList = $fileClient->handleRouteList($taskRouteArr);
                //这里检测路由定义的规范性，强制要求每个路由上面必须写注释
                if(!$fileClient->checkRouteNoteIsNorm($_SERVER["DOCUMENT_ROOT"].\FileClient::$task_path.'/route/app.php')){
                    $route_notr_norm_str .= 'task模块下的路由定义文件未符合既规范<br>';
                }
                //获取task模块下controller
                $task_controller_arr = $fileClient->selectOnlyModule($_SERVER["DOCUMENT_ROOT"].\FileClient::$admin_path.'/controller');
                foreach ($task_controller_arr as $file_name){
                    if($file_name != 'Error.php'){
                        $file_name_arr = explode('.',$file_name);
                        if(isset($taskRouteList[$file_name_arr[0]])){
                            $ownRouteList = $taskRouteList[$file_name_arr[0]];
                        }else{
                            $ownRouteList = [];
                        }
                        $content = $fileClient->readFile($_SERVER["DOCUMENT_ROOT"].\FileClient::$task_path.'/controller/'.$file_name);
                        $line_count_all += substr_count($content,"<br>");
                        $functionListAll = $fileClient->checkContentFunction($content);
                        $functionStrList = $functionListAll[0];
                        //检查方法上是否有注释
                        $funcIsValid = $fileClient->checkFunctionStr($functionStrList,explode('<br>',$content));
                        if(!$funcIsValid){
                            $func_str .= 'task下controller类【'.$file_name.'】的方法没有注释<br>';
                        }
                        //检查引入是否有固定的注释
                        $leadIntoIsValid = $fileClient->checkLeadInto(explode('<br>',$content));
                        if(!$leadIntoIsValid){
                            $lead_into_str .= 'task下controller类【'.$file_name.'】引入规范有误<br>';
                        }
                        $functionList = $functionListAll[1];
                        //检查是否遵循驼峰命名
                        $isValid = $fileClient->checkFunctionNameIsValid($functionList);
                        if(!$isValid){
                            $hump_str .= 'task下controller类【'.$file_name.'】的方法驼峰命名有误<br>';
                        }
                        if(!$fileClient->checkRouteAndFunction($ownRouteList,$functionList)){
                            $route_str .= 'task下controller类【'.$file_name.'】的路由与方法不匹配<br>';
                        }
                    }
                }
                $contentData = [
                    '代码行数' => $line_count_all,//代码行数
                    '路由匹配' => $route_str,//路由释义
                    '驼峰命名' => $hump_str,//驼峰命名
                    '方法注释' => $func_str,//方法注释
                    '引用注释' => $lead_into_str,//引用注释
                    '路由注释' => $route_notr_norm_str,
                    '验证引用别名' => $validate_require_alias_str,
                    '服务引用别名' => $service_require_alias_str,
                    '返回注释' => $return_valid_str,
                    '参数获取' => $func_data_str,
                    '模型注释' => $common_model_schema_check_str,
                    '字段注释' => $common_model_schema_remark_check_str,
                    '类名检测' => $compare_str
                ];
                YwProjectSubmitRecord::where(['id'=>$item['id']])->update([
                    'is_check' => 1,
                    'check_time' => date('Y-m-d H:i:s'),
                    'check_result' => json_encode($contentData)
                ]);
            }
        }
    }


}
